package com.syl.springcloud.authorization.controller;

import com.syl.springcloud.authorization.bean.ReturnMessage;
import com.syl.springcloud.authorization.enums.LoginTypeEnum;
import com.syl.springcloud.authorization.service.LoginService;
import org.apache.commons.lang.StringUtils;
import org.patchca.service.ConfigurableCaptchaService;
import org.patchca.utils.encoder.EncoderHelper;
import org.patchca.word.RandomWordFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.syl.springcloud.authorization.constant.LoginConstant.IMAGE_TYPE_PNG;

/**
 * @author syl
 * @create 2018-08-06 15:25
 **/
@RequestMapping("login")
@RestController
public class LoginController {

    @Autowired
    private LoginService loginService;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @RequestMapping("/password/captcha")
    public String captchaLogin(){
        return "密码登录+验证码登录页";
    }

    @RequestMapping("/sms/captcha")
    public String smsLogin(){
        return "短信验证码登录页";
    }

    @RequestMapping("/get/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String x = request.getParameter("x");
        String y = request.getParameter("y");
        String single = request.getParameter("single");
        int x_ = StringUtils.isBlank(x) ? 0 : Integer.parseInt(x);
        int y_ = StringUtils.isBlank(y) ? 0 : Integer.parseInt(y);
        boolean single_ = StringUtils.isBlank(single);
        ConfigurableCaptchaService cs = loginService.initCaptchaConfig(x_, y_, single_);
        String tempImagePath = System.getProperty("user.dir") + File.separator + UUID.randomUUID() + "." + IMAGE_TYPE_PNG;
        FileOutputStream outputStream = new FileOutputStream(tempImagePath);
        String validate_code = EncoderHelper.getChallangeAndWriteImage(cs,IMAGE_TYPE_PNG, outputStream);
        outputStream.close();// getChallangeAndWriteImage 中的流没有关闭好
        HttpSession session = request.getSession();
        session.setAttribute(LoginTypeEnum.PASSWORD_IMAGE_CAPTCHA.getSessionKey(), validate_code);
        File file = new File(tempImagePath);
        this.outputImage(file,false, response);
        file.delete(); // 删除临时文件
    }

    @RequestMapping("/get/sms/captcha")
    public ReturnMessage getSmsCaptcha(String phone,HttpSession session){
        if(StringUtils.isBlank(phone))return new ReturnMessage(400,"手机号码不能为空");
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        String lockKey = session.getId() + "_sms_send_limit";
        if(redisTemplate.hasKey(lockKey)){
            return new ReturnMessage(400,"请求太频繁了,请"+redisTemplate.getExpire(lockKey,TimeUnit.SECONDS)+"秒后再试");
        }
        RandomWordFactory rwf = new RandomWordFactory();
        rwf.setMinLength(4);
        rwf.setMaxLength(6);
        String nextWord = rwf.getNextWord();
        opsForValue.set(lockKey,"",60,TimeUnit.SECONDS);//限制60秒之内只能发送1次
        opsForValue.set(phone,nextWord,15,TimeUnit.MINUTES);//短信验证码15分钟后过期
        return new ReturnMessage(200, nextWord);
    }

    /**
     * 给前端输出指定图片
     * @param file
     * @param cache 是否使用浏览器缓存
     * @param response
     */
    @RequestMapping("/get/image")
    public void outputImage(File file,boolean cache,HttpServletResponse response){
        FileInputStream inputStream = null;
        ServletOutputStream stream = null;
        try {
            inputStream = new FileInputStream(file);
            byte[] bytes = new byte[inputStream.available()];
            inputStream.read(bytes);
            if(!cache)setNoCacheAndImage(response);//不使用缓存
            stream = response.getOutputStream();
            stream.write(bytes);
            stream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(inputStream != null)inputStream.close();
                if(stream != null)stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void setNoCacheAndImage(HttpServletResponse response){
        response.setDateHeader("Expires", 0L);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/"+IMAGE_TYPE_PNG);
    }

}
